<?php

class User_Model_Acl extends Zend_Acl
{
    public function __construct($user)
    {
        // Will hold all the groups that the user is member of
        $groups = array();
        
        // Find all default groups
        foreach (User_Model_Groups::getAllBy('is_default', true) as $group) {
            $groups[$group->id] = $group;
        }
        
        // Find the groups that the user is explicitely a member of
        if ($user) {
            $userGroups = $user->findManyToManyRowset('User_Model_Groups', 'User_Model_UsersGroups');
            foreach ($userGroups as $group) {
                $groups[$group->id] = $group;
            }
        }
        
        $groupNames = array();
        
        foreach ($groups as $group) {
            
            $groupNames[] = $group->name;
            
            // Create the group role
            $this->addRole(new Zend_Acl_Role($group->name));
            
            // Create resource for every 
            foreach ($group->getAllowedResources(true) as $resource) {
                
                // The resource name is a concatenation of module and controller
                $resourceName = $this->getResourceName($resource->module, $resource->controller);
                $privilegeName = $this->getPrivilegeName($resource->action);
                
                // Add the resource if it does not exist
                if (!$this->has($resourceName)) {
                    $this->add(new Zend_Acl_Resource($resourceName));
                }
                
                $this->allow($group->name, $resourceName, $privilegeName);
            }
        }
        
        $this->addRole(new Zend_Acl_Role('user'), $groupNames);
    }
    
    public function isUserAllowed($module, $controller, $action)
    {
        $resourceName = $this->getResourceName($module, $controller);
        $privilegeName = $this->getPrivilegeName($action);
        
        $allowed = $this->isAllowed('user', $resourceName, $privilegeName);
        
        return $allowed;
    }
    
    public function isAllowed($role = null, $resource = null, $privilege = null)
    {
        try {
            return parent::isAllowed($role, $resource, $privilege);
        } catch (Zend_Acl_Exception $e) {
            return false;
        }
    }
    
    protected function getPrivilegeName($action)
    {
        if ($action == '*') {
            return null;
        }
        
        return $action;
    }
    
    protected function getResourceName($module, $controller)
    {
        return $module . '/' . $controller;
    }
}